home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / sun / volume1 / ethertools-3.x / part02 < prev    next >
Encoding:
Text File  |  1989-06-21  |  52.5 KB  |  2,176 lines

  1. Path: uunet!lll-winken!csd4.milw.wisc.edu!bionet!apple!rutgers!aramis.rutgers.edu!dartagnan.rutgers.edu!mcgrew
  2. From: mcgrew@dartagnan.rutgers.edu (Charles Mcgrew)
  3. Newsgroups: comp.sources.sun
  4. Subject: v01i037:  Ethernet tools for SunOS 3.X, Part02/02
  5. Message-ID: <Jun.21.13.54.12.1989.29072@dartagnan.rutgers.edu>
  6. Date: 21 Jun 89 17:54:15 GMT
  7. Organization: Rutgers Univ., New Brunswick, N.J.
  8. Lines: 2165
  9. Approved: mcgrew@aramis.rutgers.edu
  10.  
  11. Submitted-by: budd@bu-it.bu.edu
  12. Posting-number: Volume 1, Issue 37
  13. Archive-name: ethertools-3.X/part02
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 2 (of 2)."
  22. # Contents:  ctp.c if_ctp.c nit.c packet.h rlog.c
  23. # Wrapped by budd@buita on Sat Aug 13 01:14:42 1988
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f ctp.c -a "${1}" != "-c" ; then 
  26.   echo shar: Will not over-write existing file \"ctp.c\"
  27. else
  28. echo shar: Extracting \"ctp.c\" \(10642 characters\)
  29. sed "s/^X//" >ctp.c <<'END_OF_ctp.c'
  30. X/*
  31. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  32. X * All Rights Reserved
  33. X *
  34. X * Permission is granted to any individual or institution to use, copy,
  35. X * or redistribute this software so long as it is not sold for profit,
  36. X * provided that this notice and the original copyright notices are
  37. X * retained.  Boston University makes no representations about the
  38. X * suitability of this software for any purpose.  It is provided "as is"
  39. X * without express or implied warranty.
  40. X */
  41. X/*
  42. X *    CTP -- Ethernet v2 Configuration Test Protocol User Process
  43. X *    Philip L. Budne @ Boston University / Distributed Systems
  44. X *
  45. X */
  46. X
  47. X# include <sys/types.h>
  48. X# include <sys/time.h>
  49. X# include <net/nit.h>
  50. X# include <signal.h>
  51. X# include <stdio.h>
  52. X# include "ctp.h"
  53. X
  54. X/*
  55. X * SIGH.  Move sender to child?
  56. X * print loss.
  57. X * print variance.
  58. X */
  59. X
  60. X# define SHM
  61. X
  62. Xtypedef u_char ea_t[6];            /* ethernet address type */
  63. X
  64. X# ifdef SHM
  65. X# include <sys/ipc.h>
  66. X# include <sys/shm.h>
  67. X
  68. Xint shmid;
  69. Xchar *shmaddr, *shmat();
  70. X
  71. X# define NCOUNTS 8
  72. X# define NCOUNT (1<<(NCOUNTS))
  73. Xstruct stats {
  74. X    int total;                /* total count */
  75. X    int highseq;            /* highest seq seen */
  76. X    int outofseq;            /* number recvd out of sequence */
  77. X    int min, max;            /* min and max times */
  78. X    int sum, sumsq;            /* sum of times, sum of squares */
  79. X    int counts[ NCOUNT ];
  80. X    /* array of addrs? */
  81. X};
  82. X
  83. Xint lastseq = 0;
  84. Xint nsent = 0;
  85. X# endif /* SHM defined */
  86. X
  87. Xint seq = 0;
  88. X
  89. Xstruct packet {                /* CTP packet layout */
  90. X    ea_t    p_dst;            /* Ethernet dest */
  91. X    ea_t    p_src;            /* Ethernet src */
  92. X    u_short p_type;            /* Ethernet type (802 length) */
  93. X    u_short p_skip;            /* CTP skip */
  94. X    u_char  p_data[ 2048 ];        /* ... */
  95. X};
  96. X
  97. Xstruct ctp_forward {            /* forward subpacket */
  98. X    u_short cf_function;        /* CTP_FWD */
  99. X    ea_t    cf_addr;
  100. X};
  101. X
  102. Xstruct ctp_reply {            /* reply subpacket */
  103. X    u_short cr_function;        /* CTP_REP */
  104. X    /* The following is data that we use for own purposes */
  105. X    u_short cr_pid;            /* pid of sender -- not swapped */
  106. X    u_short cr_seq;            /* sequence number -- not swapped */
  107. X    struct timeval cr_sendt;        /* time packet was sent */
  108. X    /* more data here.. */
  109. X};
  110. X
  111. Xea_t localaddr;                /* our ethernet address */
  112. X
  113. X# define MAXPATH 200            /* !! (more than can fit in a packet) */
  114. Xea_t path[ MAXPATH];            /* path list */
  115. Xint pathcount = 0;            /* length of path list */
  116. X
  117. X# define MINPACK 60            /* minimum ether packet */
  118. X# define MAXPACK 1516            /* maximum ether packet */
  119. X
  120. Xint count = -1;                /* number of packets to send */
  121. Xchar ifbuf[ 100 ];
  122. Xchar *interface = ifbuf;        /* interface to use */
  123. Xint verbose = 0;            /* extra output */
  124. Xint noreturn = 0;            /* don't force final forward back */
  125. Xint debug = 0;                /* don't fork */
  126. Xint packlen = MINPACK;            /* default total packet length */
  127. Xint slptim = 1000;            /* sleep time in ms */
  128. X
  129. Xint pid;                /* parent pid */
  130. Xint child;                /* child pid */
  131. X
  132. Xmain(argc, argv)
  133. X    int argc;
  134. X    char *argv[];
  135. X{
  136. X    extern char *optarg;
  137. X    extern int optind, opterr;
  138. X    int s, c, errs;
  139. X    void nit_input();            /* forward */
  140. X
  141. X    errs = 0;
  142. X    while( (c = getopt( argc, argv, "c:di:l:ns:v" )) != EOF ) {
  143. X    switch( c ) {
  144. X    case 'c':
  145. X        count = atoi( optarg );
  146. X        break;
  147. X    case 'd':
  148. X        debug ^= 1;
  149. X        break;
  150. X    case 'i':
  151. X        interface = optarg;
  152. X        break;
  153. X    case 'l':
  154. X        packlen = atoi( optarg );
  155. X        if( packlen < MINPACK )
  156. X        packlen = MINPACK;
  157. X        else if( packlen > MAXPACK )
  158. X        packlen = MAXPACK;
  159. X        break;
  160. X    case 'n':
  161. X        noreturn ^= 1;
  162. X        break;
  163. X    case 's':
  164. X        slptim = atoi( optarg );
  165. X        break;
  166. X    case 'v':
  167. X        verbose ^= 1;
  168. X        break;
  169. X    default:
  170. X        errs++;
  171. X    } /* switch */
  172. X    } /* while getopt */
  173. X    if( errs > 0 ) {
  174. X    fprintf( stderr, "Usage: %s [-c count] [-d] [-i ifn] ", argv[0] );
  175. X    fprintf( stderr, "[-l len] [-n] [-s sleep] [-v] [addr ...]\n");
  176. X    fprintf( stderr, "addr <- ether-addr | ipaddr | iphost | ");
  177. X    fprintf( stderr, "etherhost | 'BCAST' | 'MCAST'\n" );
  178. X    exit( 1 );
  179. X    }
  180. X
  181. X    pid = getpid();            /* get parent pid */
  182. X    s = nit_open( interface, ETHERTYPE_CTP, localaddr, 0 );
  183. X    printf("%s address ", interface );
  184. X    petaddr( localaddr );
  185. X    puts( "" );
  186. X
  187. X    pathcount = 0;
  188. X    while( optind < argc && pathcount < MAXPATH && argv[optind] != NULL ) {
  189. X    if( strcmp( argv[optind], "MCAST" ) == 0 ) {    /* CTP mcast addr */
  190. X        register u_char *ea;
  191. X        ea = path[pathcount];
  192. X        *ea++ = 0XCF;
  193. X        *ea++ = 0x00;
  194. X        *ea++ = 0x00;
  195. X        *ea++ = 0x00;
  196. X        *ea++ = 0x00;
  197. X        *ea   = 0x00;
  198. X    }
  199. X    else if( !htoea( argv[ optind ], path[pathcount] ) ) {
  200. X        fprintf( stderr, "%s: unknown host %s\n",
  201. X            argv[0], argv[optind] );
  202. X        exit( 1 );
  203. X    } /* bad host */
  204. X    pathcount++;
  205. X    optind++;
  206. X    } /* while hosts */
  207. X
  208. X    if( pathcount == 0 ) {        /* if no hosts */
  209. X    bcopy( bcast, path[0], sizeof( ea_t ) ); /* broadcast */
  210. X    pathcount++;            /* fake count */
  211. X    } /* empty path */
  212. X
  213. X    if( debug )
  214. X    ctp_send( s );            /* just send */
  215. X    else {
  216. X# ifdef SHM
  217. X    void gotint(), die(), poop();
  218. X    struct stats *sp;
  219. X
  220. X    signal( SIGINT, gotint );
  221. X    signal( SIGHUP, die );
  222. X    signal( SIGKILL, die );
  223. X
  224. X    shmid = shmget( IPC_PRIVATE, sizeof( struct stats ), 0600 );
  225. X    shmaddr = shmat( shmid, 0, 0 );
  226. X    sp = (struct stats *)shmaddr;
  227. X    bzero( sp, sizeof( struct stats ) );
  228. X    sp->min = 100000;
  229. X    sp->max = -1;
  230. X# endif /* SHM defined */
  231. X
  232. X    switch( (child = fork()) ) {
  233. X    case -1:
  234. X        perror( "fork" );
  235. X        exit( 1 );
  236. X        /* NOTREACHED */
  237. X
  238. X    case 0:
  239. X# ifdef SHM
  240. X        signal( SIGINT,  poop );
  241. X        signal( SIGHUP,  poop );
  242. X        signal( SIGKILL, poop );
  243. X# endif /* SHM defined */
  244. X        nit_loop( s, nit_input );    /* input in child */
  245. X        /* NOTREACHED */
  246. X
  247. X    default:
  248. X        ctp_send(s);        /* output in parent */
  249. X        /* NOTREACHED */
  250. X    } /* switch */
  251. X    }
  252. X} /* main */
  253. X
  254. X# ifdef SHM
  255. Xvoid
  256. Xdie() {
  257. X    (void) shmdt( shmaddr );
  258. X    (void) shmctl( shmid, IPC_RMID, 0 );
  259. X    exit( 0 );
  260. X}
  261. X
  262. Xvoid
  263. Xpoop() {
  264. X    exit( 1 );
  265. X}
  266. X
  267. Xvoid
  268. Xstats() {
  269. X    register struct stats *sp;
  270. X
  271. X    sp = (struct stats *) shmaddr;
  272. X    printf("----CTP statistics----\n");
  273. X    printf("%d Packet%s Sent, %d Recieved\n",
  274. X       nsent, (nsent == 1 ? "" : "s"), sp->total );
  275. X    if( sp->total > 0 )
  276. X    printf("round-trip (ms)  min/avg/max = %d/%d/%d var=%d\n",
  277. X           sp->min, sp->sum / sp->total, sp->max,
  278. X           0 );
  279. X} /* stats */
  280. X
  281. Xvoid
  282. Xgotint() {
  283. X    puts("");
  284. X    stats();
  285. X    die();
  286. X}
  287. X
  288. X# endif /* SHM defined */
  289. X
  290. X/****************************************************************/
  291. X
  292. Xvoid
  293. Xnit_input( s, nh )
  294. X    int s;
  295. X    struct nit_hdr *nh;
  296. X{
  297. X    int l;
  298. X    u_char *p2;
  299. X    int len, l2, ms;
  300. X    short f, skip, seq;
  301. X    struct packet *pp;
  302. X    struct ctp_reply *cr;
  303. X# ifdef SHM
  304. X    register struct stats *sp;
  305. X    sp = (struct stats *) shmaddr;
  306. X# endif /* SHM defined */
  307. X
  308. X    l = nh->nh_datalen;
  309. X    pp = (struct packet *) (((u_char *)nh) + sizeof( struct nit_hdr ));
  310. X    
  311. X    skip = pp->p_skip;            /* fetch skip */
  312. X    skip = SSWAP( skip );        /* swap it */
  313. X
  314. X    if( skip & 1 )
  315. X    return;                /* skip must not be odd */
  316. X
  317. X    p2 = (u_char *) pp->p_data + skip;
  318. X    len = l - 14 - skip - 2;        /* length of data */
  319. X
  320. X    if( len < 2 )            /* no room for function */
  321. X    return;
  322. X
  323. X    cr = (struct ctp_reply *) p2;    /* get reply struct */
  324. X    f = CTP_SHORT( p2 );        /* get function */
  325. X    p2 += 2;                /* advance past function */
  326. X    len -= 2;                /* account for function length */
  327. X    switch( f ) {
  328. X    case CTP_REP:            /* reply */
  329. X    break;
  330. X
  331. X    case CTP_FWD:
  332. X    return;                /* we are a client. */
  333. X    break;
  334. X
  335. X    default:
  336. X/*    printf(" fncn %d. data: ", f );    /* !! */
  337. X    return;
  338. X    }
  339. X
  340. X    if( cr->cr_pid != pid )        /* check for parent pid */
  341. X    return;
  342. X
  343. X    p2 += 2;                /* advance past pid */
  344. X    len -= 4;                /* pid, seq */
  345. X
  346. X    printf("%d bytes from ", l );
  347. X    petaddr( pp->p_src );
  348. X    seq = CTP_SHORT( p2 );
  349. X    ms = delta( &nh->nh_timestamp, &cr->cr_sendt );
  350. X    printf(": seq %2d. time=%dms\n", seq, ms );
  351. X
  352. X# ifdef SHM
  353. X    sp->total++;
  354. X    if( seq != lastseq && seq != lastseq+1 )
  355. X    sp->outofseq++;
  356. X    lastseq = seq;
  357. X    if( ms > sp->max )
  358. X    sp->max = ms;
  359. X    if( ms < sp->min )
  360. X    sp->min = ms;
  361. X    if( seq > sp->highseq )
  362. X    sp->highseq = seq;
  363. X    sp->sum += ms;
  364. X    sp->sumsq = ms * ms;
  365. X    sp->counts[ seq & (NCOUNT-1) ]++;
  366. X# endif /* SHM defined */
  367. X} /* nit_input */
  368. X
  369. Xdelta( a, b )
  370. X    struct timeval *a, *b;
  371. X{
  372. X    int usec, sec;
  373. X    usec = a->tv_usec - b->tv_usec;
  374. X    sec  = a->tv_sec  - b->tv_sec;
  375. X
  376. X    if( usec < 0 )   {
  377. X    sec--;
  378. X    usec += 1000000;
  379. X    }
  380. X    usec += 999;            /* round to ms */
  381. X    sec = sec * 1000 + usec / 1000;    /* get ms */
  382. X    if( sec < 0 ) {
  383. X    printf("a: %d %d b: %d %d\n",
  384. X           a->tv_sec, a->tv_usec,
  385. X           b->tv_sec, b->tv_usec );
  386. X    return( 0 );
  387. X    } /* sec < 0 */
  388. X    return( sec );
  389. X} /* delta */
  390. X
  391. X/****************************************************************/
  392. X
  393. Xctp_send( s )
  394. X    int s;
  395. X{
  396. X    struct timezone tz;
  397. X    struct ctp_forward *cf;
  398. X    struct ctp_reply *cr, *ocr;
  399. X    struct packet p;
  400. X    u_char *cp;
  401. X    int i, c;
  402. X
  403. X    printf("to ");
  404. X    for( i = 0; i < pathcount; i++ ) {
  405. X    if( i > 0 )
  406. X        printf(", ");
  407. X    petaddr( path[i] );
  408. X    }
  409. X
  410. X    /* fill in ether packet header */
  411. X    bcopy( path[ 0 ], p.p_dst, sizeof( p.p_dst ) ); /* fill in initial dest */
  412. X    p.p_type = ETHERTYPE_CTP;        /* fill in type */
  413. X    p.p_skip = SSWAP( 0 );        /* fill in initial CTP skip */
  414. X
  415. X    cf = (struct ctp_forward *) p.p_data; /* get data pointer */
  416. X    for( i = 1; i < pathcount; i++ ) {
  417. X    cf->cf_function = SSWAP( CTP_FWD );
  418. X    bcopy( path[i], cf->cf_addr, sizeof( ea_t ) );
  419. X    cf++;                /* advance pointer */
  420. X    }
  421. X
  422. X    /* ensure packet gets back -- append forward to ourselves */
  423. X    if( !noreturn &&
  424. X       bcmp( path[pathcount-1], localaddr, sizeof( localaddr ) ) != 0 ) {
  425. X    cf->cf_function = SSWAP( CTP_FWD );
  426. X    bcopy( localaddr, cf->cf_addr, sizeof( localaddr ) );
  427. X    cf++;
  428. X    }
  429. X
  430. X    /* create reply data */
  431. X    cr = (struct ctp_reply *) cf;
  432. X    cr->cr_function = SSWAP( CTP_REP );
  433. X    cr->cr_pid = pid;            /* pid of parent */
  434. X    ocr = cr;                /* save pointer for timestamp */
  435. X    cr++;                /* advance past reply */
  436. X
  437. X    cp = (u_char *) cr;            /* get pointer to reply data */
  438. X    i = cp - (u_char *)&p;        /* get length of packet so far */
  439. X
  440. X    if( i > packlen )
  441. X    if( i > MAXPACK ) {
  442. X        fprintf( stderr, "Packet too large without data (%d)\n", i );
  443. X        exit( 1 );
  444. X    }
  445. X    else
  446. X        packlen = i;
  447. X
  448. X    printf(": %d data bytes (%d total)\n", packlen - i, packlen );
  449. X    fflush( stdout );
  450. X
  451. X    while( i < packlen )
  452. X    *cp++ = i++ & 0xff;
  453. X
  454. X    slptim *= 1000;            /* convert to usec */
  455. X    while( count != 0 ) {
  456. X    if( count > 0 )
  457. X        count--;
  458. X    ocr->cr_seq = SSWAP( seq );
  459. X    seq++;                /* update sequence */
  460. X    gettimeofday( &ocr->cr_sendt, &tz );
  461. X
  462. X    if( nit_output( s, &p, packlen ) < 0 )
  463. X        perror( "write" );
  464. X    else
  465. X        nsent++;
  466. X    usleep( slptim ); 
  467. X    }
  468. X    kill( child, SIGINT );
  469. X    stats();
  470. X    die();
  471. X} /* ctp_send */ 
  472. END_OF_ctp.c
  473. if test 10642 -ne `wc -c <ctp.c`; then
  474.     echo shar: \"ctp.c\" unpacked with wrong size!
  475. fi
  476. # end of overwriting check
  477. fi
  478. if test -f if_ctp.c -a "${1}" != "-c" ; then 
  479.   echo shar: Will not over-write existing file \"if_ctp.c\"
  480. else
  481. echo shar: Extracting \"if_ctp.c\" \(5585 characters\)
  482. sed "s/^X//" >if_ctp.c <<'END_OF_if_ctp.c'
  483. X/*
  484. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  485. X * All Rights Reserved
  486. X *
  487. X * Permission is granted to any individual or institution to use, copy,
  488. X * or redistribute this software so long as it is not sold for profit,
  489. X * provided that this notice and the original copyright notices are
  490. X * retained.  Boston University makes no representations about the
  491. X * suitability of this software for any purpose.  It is provided "as is"
  492. X * without express or implied warranty.
  493. X */
  494. X/*
  495. X * if_ctp.c -- Ethernet Version 2 Configuation Test Protocol (CTP)
  496. X *
  497. X * DEC DEUNA does this at the controller level??
  498. X */
  499. X
  500. X
  501. X/*
  502. X * Called from do_protocol in sunif/if_subr.c;
  503. X *
  504. X *#endif INET
  505. X>*#ifdef ETHERPUP_CTPTYPE:
  506. X>*    case ETHERPUP_CTPTYPE:
  507. X>*        ctp_input( header, m, &ap->ac_if );
  508. X>*        break;
  509. X>*#endif ETHERPUP_CTPTYPE:
  510. X *    default:
  511. X */
  512. X
  513. X/*
  514. X * add to /sys/conf/files;
  515. X * sunif/if_ctp.c        optional ether
  516. X */
  517. X
  518. X/* add to netinet/if_ether.h;
  519. X/* #define ETHERTYPE_CTP    0x9000        /* Config. Test Protocol */
  520. X/* ... */
  521. X/* #define ETHERPUP_CTPTYPE    0x9000        /* Config. Test Protocol */
  522. X
  523. X
  524. X# include "ether.h"
  525. X
  526. X# if NETHER > 0
  527. X# include "../h/param.h"
  528. X# include "../h/systm.h"
  529. X# include "../h/mbuf.h"
  530. X# include "../h/socket.h"
  531. X# include "../h/time.h"
  532. X# include "../h/kernel.h"
  533. X# include "../h/errno.h"
  534. X# include "../h/ioctl.h"
  535. X
  536. X# include "../net/if.h"
  537. X# include "../netinet/in.h"        /* for if_ether */
  538. X# include "../netinet/if_ether.h"    /* for ether_header */
  539. X
  540. X# define DEBUG
  541. X
  542. X# define CTP_REP 1
  543. X# define CTP_FWD 2
  544. X
  545. X# if defined(vax) || defined(ns32000)    /* machine is a byteswapper? */
  546. X# define SWAP(s) (s)            /* CTP wants them swapped!! */
  547. X# else /* not defined(vax) || defined(ns32000) */
  548. X# define SWAP(s) ((((s)>>8) & 0xff) | (((s)<<8) & 0xff00))
  549. X# endif /* not defined(vax) || defined(ns32000) */
  550. X
  551. X# ifndef ETHERTYPE_CTP
  552. X# define ETHERTYPE_CTP 0x9000        /* 90-00 */
  553. X# endif /* ETHERTYPE_CTP not defined */
  554. X
  555. X# define SP(s) ((u_short *)s)
  556. X# define SS (sizeof(short))
  557. X
  558. Xint ctp_rawinput;            /* total input */
  559. Xint ctp_reply;                /* replies to us */
  560. Xint ctp_forward;            /* packets forwarded */
  561. Xint ctp_multicast;            /* err: forward to multicast!! */
  562. Xint ctp_badfunction;            /* err: bad function */
  563. Xint ctp_errs;                /* other errs */
  564. Xctp_input( h, m, myif )
  565. X    register struct ether_header *h;
  566. X    register struct mbuf *m;
  567. X    struct ifnet *myif;
  568. X{
  569. X    ctp_rawinput++;
  570. X
  571. X    if( !ctp_process( h, m ) )        /* no reply generated?? */
  572. X    m_freem(m);            /* discard buffer */
  573. X}
  574. X
  575. Xstatic ctp_process( h, m, myif )
  576. X    register struct ether_header *h;
  577. X    register struct mbuf *m;
  578. X    struct ifnet *myif;
  579. X{
  580. X    register u_short func, skip;
  581. X    register u_char *cp;
  582. X    register int l;
  583. X
  584. X    struct ether_header *eh;
  585. X    struct sockaddr sa;
  586. X
  587. X    l = m->m_len;            /* get data length */
  588. X    cp = mtod(m, u_char *);        /* get data pointer */
  589. X
  590. X    /****************************************************************
  591. X     * process skip
  592. X     */
  593. X
  594. X    l -= SS;
  595. X    if( l < 0 ) {
  596. X# ifdef DEBUG
  597. X    ctp_msg( h );
  598. X    printf("-- too short for skip\n", skip );
  599. X# endif /* DEBUG defined */
  600. X    ctp_errs++;
  601. X    return( 0 );            /* no reply generated */
  602. X    }
  603. X
  604. X    skip = *SP( cp );            /* get skip */
  605. X    skip = SWAP( skip );        /* byte swap if needed */
  606. X    cp += SS;
  607. X
  608. X    if( skip & 1 ) {
  609. X# ifdef DEBUG
  610. X    ctp_msg( h );
  611. X    printf("-- odd skip %d\n", skip );
  612. X# endif /* DEBUG defined */
  613. X    ctp_errs++;
  614. X    return( 0 );            /* no reply generated */
  615. X    }
  616. X
  617. X    /****************************************************************
  618. X     * process function
  619. X     */
  620. X
  621. X    l -= skip;
  622. X    if( l < 0 ) {
  623. X# ifdef DEBUG
  624. X    ctp_msg( h );
  625. X    printf("-- skip too large (%d.)\n", skip );
  626. X# endif /* DEBUG defined */
  627. X    ctp_errs++;
  628. X    return( 0 );            /* no reply generated */
  629. X    }
  630. X
  631. X    cp += skip;                /* get address of function */
  632. X
  633. X    func = *SP( cp );            /* get function */
  634. X    func = SWAP( func );        /* byte swap if needed */
  635. X
  636. X    l -= SS;                /* deduct function length */
  637. X    cp += SS;                /* advance past function */
  638. X
  639. X    switch( func ) {
  640. X
  641. X    case CTP_REP:            /* reply */
  642. X# ifdef DEBUG
  643. X    ctp_msg( h );
  644. X    printf("-- reply, %d bytes\n", l);
  645. X# endif /* DEBUG defined */
  646. X    /* create AF_CTP and pass up to users?? */
  647. X    ctp_reply++;
  648. X    return( 0 );            /* no reply generated */
  649. X    break;
  650. X
  651. X    case CTP_FWD:
  652. X    l -= sizeof( struct ether_addr );
  653. X    if( l < 0 ) {
  654. X# ifdef DEBUG
  655. X        ctp_msg( h );
  656. X        printf("-- forward too short\n");
  657. X# endif /* DEBUG defined */
  658. X        ctp_errs++;
  659. X        return( 0 );
  660. X    }
  661. X    if( *cp & 1 ) {            /* multicast bit */
  662. X        ctp_msg( h );
  663. X        printf(" -- forward to multicast address ");
  664. X        ether_print( cp );
  665. X        printf(" ignored\n");
  666. X        ctp_multicast++;
  667. X        return( 0 );        /* no reply generated */
  668. X    }
  669. X# ifdef DEBUG
  670. X    ctp_msg( h );
  671. X    printf("-- forwarding %d bytes to ", l);
  672. X    ether_print( cp );
  673. X# endif /* DEBUG defined */
  674. X    skip += SS + sizeof( struct ether_addr ); /* skip forward function */
  675. X                    /* and address */
  676. X    *mtod(m, u_short *) = SWAP( skip ); /* update in packet */
  677. X
  678. X    sa.sa_family = AF_UNSPEC;        /* set family */
  679. X    eh = (struct ether_header *)sa.sa_data;    /* get sockaddr */
  680. X    eh->ether_type = ETHERTYPE_CTP;        /* set ether type */
  681. X    eh->ether_dhost = *(struct ether_addr *) cp; /* copy dest */
  682. X    (myif->if_output)( myif, m, &sa );
  683. X
  684. X    ctp_forward++;
  685. X    return( 1 );            /* AH-HAH!! we generated a reply!! */
  686. X    break;
  687. X
  688. X    default:
  689. X# ifdef DEBUG
  690. X    ctp_msg( h );
  691. X    printf("-- bad function %d.\n", func );
  692. X# endif /* DEBUG defined */
  693. X    ctp_badfunction++;
  694. X    return( 0 );
  695. X    break;
  696. X    }
  697. X    return( 0 );            /* just in case */
  698. X} /* ctp_process */
  699. X
  700. Xctp_msg( h )
  701. X    register struct ether_header *h;
  702. X{
  703. X    printf("CTP packet from ");
  704. X    ether_print( &h->ether_shost );
  705. X} /* ctp_msg */
  706. X
  707. X# endif /* NETHER > 0 */
  708. END_OF_if_ctp.c
  709. if test 5585 -ne `wc -c <if_ctp.c`; then
  710.     echo shar: \"if_ctp.c\" unpacked with wrong size!
  711. fi
  712. # end of overwriting check
  713. fi
  714. if test -f nit.c -a "${1}" != "-c" ; then 
  715.   echo shar: Will not over-write existing file \"nit.c\"
  716. else
  717. echo shar: Extracting \"nit.c\" \(5414 characters\)
  718. sed "s/^X//" >nit.c <<'END_OF_nit.c'
  719. X/*
  720. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  721. X * All Rights Reserved
  722. X *
  723. X * Permission is granted to any individual or institution to use, copy,
  724. X * or redistribute this software so long as it is not sold for profit,
  725. X * provided that this notice and the original copyright notices are
  726. X * retained.  Boston University makes no representations about the
  727. X * suitability of this software for any purpose.  It is provided "as is"
  728. X * without express or implied warranty.
  729. X */
  730. X# include <sys/types.h>
  731. X# include <sys/time.h>
  732. X# include <sys/socket.h>
  733. X# include <sys/ioctl.h>
  734. X# include <net/nit.h>
  735. X# include <net/if.h>
  736. X# include <stdio.h>
  737. X
  738. X# define GLOBAL
  739. X
  740. X# ifdef DEBUG
  741. X# define IFDEB(x) (x)
  742. X# else /* DEBUG not defined */
  743. X# define IFDEB(x)
  744. X# endif /* DEBUG not defined */
  745. X
  746. X# define ALIGNSIZE sizeof( int )
  747. X# define ALIGN(a) (((a) + ALIGNSIZE - 1) & ~(ALIGNSIZE - 1))
  748. X/* NITBUFSIZ == 1K */
  749. X# define BUFSPACE (NITBUFSIZ * 256)
  750. X# define CHUNKSIZE (NITBUFSIZ * 64)
  751. X/****************************************************************/
  752. X
  753. X
  754. XGLOBAL int nit_errors = 1;        /* display errors */
  755. XGLOBAL int nit_exit = 1;        /* exit on errors */
  756. XGLOBAL int nit_bufspace = BUFSPACE;
  757. XGLOBAL int nit_chunksize = CHUNKSIZE;
  758. XGLOBAL int nit_snaplen = 2000;
  759. X
  760. Xtypedef void (*FPTR)();
  761. X
  762. XGLOBAL int
  763. Xnit_loop( s, input_handlr )
  764. X    int s;
  765. X    FPTR input_handlr;
  766. X{
  767. X    for( ;; ) {
  768. X    static char buf[ BUFSPACE ];
  769. X    register char *pp;
  770. X    register struct nit_hdr *nh;
  771. X    char *pe;
  772. X    int cc;
  773. X
  774. X    cc = read( s, buf, sizeof( buf ) );
  775. X    if( cc < sizeof( struct nit_hdr ) ) {
  776. X        if( nit_errors )
  777. X        fprintf(stderr, "nit_loop: short read (%d)\n", cc );
  778. X        if( nit_exit )
  779. X        exit( 1 );
  780. X        else
  781. X        return( -1 );
  782. X    } /* short read */
  783. X
  784. X    pp = buf;
  785. X    pe = pp + cc;
  786. X    while( pp < pe ) {
  787. X        nh = (struct nit_hdr *) pp;
  788. X        cc = process_nh( s, nh, input_handlr );
  789. X        if( cc < 0 )
  790. X        break;
  791. X        else
  792. X        pp += ALIGN( sizeof( struct nit_hdr ) + cc );
  793. X    } /* while */
  794. X    } /* for ever */
  795. X} /* nit_process */
  796. X
  797. Xstatic int
  798. Xprocess_nh( s, nh, input_handlr )
  799. X    int s;
  800. X    struct nit_hdr *nh;
  801. X    FPTR input_handlr;
  802. X{
  803. X    switch( nh->nh_state ) {
  804. X    case NIT_QUIET:
  805. X    IFDEB( fprintf(stderr, "quiet\n") );
  806. X    return( 0 );
  807. X
  808. X    case NIT_CATCH:
  809. X    (*input_handlr)( s, nh );
  810. X    return( nh->nh_datalen );
  811. X
  812. X    case NIT_NOMBUF:
  813. X    fprintf(stderr, "out of mbufs, dropped %d packets\n",
  814. X        nh->nh_dropped );
  815. X    return( 0 );
  816. X    
  817. X    case NIT_NOCLUSTER:
  818. X    fprintf(stderr, "out of mclusters, dropped %d packets\n",
  819. X        nh->nh_dropped );
  820. X    return( 0 );
  821. X    
  822. X    case NIT_NOSPACE:
  823. X    fprintf(stderr, "bufspace exceeded, dropped %d packets\n",
  824. X        nh->nh_dropped );
  825. X    return( 0 );
  826. X    
  827. X    case NIT_SEQNO:
  828. X    IFDEB( fprintf(stderr, "seqno %d\n", nh->nh_seqno ) );
  829. X    return( 0 );
  830. X
  831. X    default:
  832. X    fprintf(stderr, "bad NIT state: %d\n", nh->nh_state );
  833. X    return( -1 );
  834. X    } /* switch */
  835. X}
  836. X
  837. XGLOBAL int
  838. Xnit_open( ifa, type, la, pro )
  839. X    char *ifa;
  840. X    unsigned int type;
  841. X    u_char *la;
  842. X    int pro;
  843. X{
  844. X    struct sockaddr_nit snit;
  845. X    struct nit_ioc nioc;
  846. X    struct ifreq ifr;
  847. X    int s;
  848. X
  849. X    if( ifa == NULL ) {
  850. X    if( nit_errors )
  851. X        fprintf( stderr, "nit_open: must have interface pointer\n" );
  852. X    if( nit_exit )
  853. X        exit( 1 );
  854. X    else
  855. X        return( -1 );
  856. X    } /* no ifa */
  857. X
  858. X    if( (s = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW)) < 0 ) {
  859. X    if( nit_errors )
  860. X        perror( "socket" );
  861. X    if( nit_exit )
  862. X        exit( 1 );
  863. X    else
  864. X        return( -1 );
  865. X    } /* socket */
  866. X
  867. X    if( *ifa == '\0' ) {        /* no interface specified */
  868. X    struct ifconf ifc;
  869. X    char ifbuf[ 100 ];
  870. X
  871. X    ifc.ifc_len = sizeof( ifbuf );
  872. X    ifc.ifc_buf = ifbuf;
  873. X
  874. X    if( ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0 ) {
  875. X        if( nit_errors )
  876. X        perror( "ifconf ioctl");
  877. X        close( s );
  878. X        if( nit_exit )
  879. X        exit( 1 );
  880. X        else
  881. X        return( -1 );
  882. X    } /* ifconf failed */
  883. X    strcpy( ifa, ifc.ifc_req->ifr_name ); /* copy back to buffer */
  884. X    } /* try to find an interface */
  885. X
  886. X    snit.snit_family = AF_NIT;
  887. X    strncpy( snit.snit_ifname, ifa, sizeof(snit.snit_ifname ) );
  888. X    if( bind(s, (struct sockaddr *)&snit, sizeof( snit ) ) < 0 ) {
  889. X    if( nit_errors )
  890. X        perror( ifa );
  891. X    close( s );
  892. X    if( nit_exit )
  893. X        exit( 1 );
  894. X    else
  895. X        return( -1 );
  896. X    } /* bind failed */
  897. X
  898. X    bzero(&nioc, sizeof(nioc));
  899. X    nioc.nioc_bufspace = nit_bufspace;
  900. X    nioc.nioc_chunksize = nit_chunksize;
  901. X    nioc.nioc_typetomatch = type;
  902. X    nioc.nioc_snaplen = nit_snaplen;
  903. X    nioc.nioc_bufalign = ALIGNSIZE;
  904. X    nioc.nioc_bufoffset = 0;
  905. X    nioc.nioc_flags = (pro ? NF_PROMISC : 0 ) | NF_TIMEOUT;   
  906. X    nioc.nioc_timeout.tv_sec = 1;
  907. X    nioc.nioc_timeout.tv_usec = 0;
  908. X    if (ioctl(s, SIOCSNIT, &nioc) != 0) {
  909. X    if( nit_errors )
  910. X        perror("nit ioctl");
  911. X    close( s );
  912. X    if( nit_exit )
  913. X        exit(1);
  914. X    else
  915. X        return( -1 );
  916. X    } /* nit ioctl */
  917. X
  918. X    strncpy(ifr.ifr_name, ifa, sizeof ifr.ifr_name);
  919. X    if( ioctl(s, SIOCGIFADDR, (caddr_t) &ifr) < 0 ) {
  920. X    if( nit_errors )
  921. X        fprintf(stderr, "cannot find ether address for %s\n", ifa );
  922. X    close( s );
  923. X    if( nit_exit )
  924. X        exit( 1 );
  925. X    else
  926. X        return( -1 );
  927. X    } /* interface address ioctl */
  928. X    bcopy( ifr.ifr_addr.sa_data, la, 6 );
  929. X    return( s );
  930. X} /* nit_open */
  931. X
  932. XGLOBAL int
  933. Xnit_output(fd, buf, len)
  934. X    int fd, len;
  935. X    char *buf;
  936. X{
  937. X    struct sockaddr sa;
  938. X    int offset = sizeof(sa.sa_data);
  939. X    int result;
  940. X
  941. X    sa.sa_family = AF_UNSPEC;
  942. X    bcopy(buf, sa.sa_data, offset);
  943. X    result = sendto(fd, buf+offset, len-offset, 0, &sa, sizeof(sa));
  944. X    if( result < 0 )
  945. X    return( result );
  946. X    return( result+offset );
  947. X} /* nit_output */
  948. END_OF_nit.c
  949. if test 5414 -ne `wc -c <nit.c`; then
  950.     echo shar: \"nit.c\" unpacked with wrong size!
  951. fi
  952. # end of overwriting check
  953. fi
  954. if test -f packet.h -a "${1}" != "-c" ; then 
  955.   echo shar: Will not over-write existing file \"packet.h\"
  956. else
  957. echo shar: Extracting \"packet.h\" \(6347 characters\)
  958. sed "s/^X//" >packet.h <<'END_OF_packet.h'
  959. X/*
  960. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  961. X * All Rights Reserved
  962. X *
  963. X * Permission is granted to any individual or institution to use, copy,
  964. X * or redistribute this software so long as it is not sold for profit,
  965. X * provided that this notice and the original copyright notices are
  966. X * retained.  Boston University makes no representations about the
  967. X * suitability of this software for any purpose.  It is provided "as is"
  968. X * without express or implied warranty.
  969. X */
  970. Xtypedef unsigned char byte;
  971. Xtypedef unsigned short u_short;
  972. Xtypedef unsigned long ip_addr;
  973. Xtypedef unsigned long u_long;
  974. Xtypedef byte EA[6];
  975. X
  976. X/****************************************************************/
  977. Xstruct ipheader {
  978. X# ifdef SWAP
  979. X    int ip_ihl : 4;        /* Internet header length in 32 bit words */
  980. X    int ip_ver : 4;        /* Header version */
  981. X# else /* SWAP not defined */
  982. X    int ip_ver : 4;        /* Header version */
  983. X    int ip_ihl : 4;        /* Internet header length in 32 bit words */
  984. X# endif /* SWAP not defined */
  985. X    byte ip_tsrv;        /* Type of service */
  986. X    u_short ip_len;        /* Total packet length including header */
  987. X    u_short ip_id;        /* ID for fragmentation */
  988. X# ifdef SWAP
  989. X    u_short ip_foff : 13;    /* Fragment offset */
  990. X    u_short ip_flgs : 3;    /* flags */
  991. X# else /* SWAP not defined */
  992. X    u_short ip_flgs : 3;    /* flags */
  993. X    u_short ip_foff : 13;    /* Fragment offset */
  994. X# endif /* SWAP not defined */
  995. X# define IP_FLG_DF 01
  996. X# define IP_FLG_MF 02
  997. X
  998. X    byte ip_ttl;        /* Time to live (secs) */
  999. X    byte ip_prot;        /* protocol */
  1000. X    u_short ip_chksum;        /* Header checksum */
  1001. X    ip_addr ip_src;        /* Source addrt */
  1002. X    ip_addr ip_dst;        /* Destination addr */
  1003. X    byte ip_options[1];        /* options... */
  1004. X};
  1005. X                    /* from RFC990 */
  1006. X# define IP_PROT_ICMP    1        /* control messages */
  1007. X# define IP_PROT_GGP    2        /* gave vs gate */
  1008. X                    /* 5 - ST - stream */
  1009. X# define IP_PROT_TCP    6        /* tcp */
  1010. X# define IP_PROT_EGP    8        /* ext gateways */
  1011. X                    /* 9 - any igp */
  1012. X# define IP_PROT_PUP    12        /* pup */
  1013. X                    /* 13 - ARGUS */
  1014. X                    /* 14 - EMCON */
  1015. X                    /* 15 - XNET - cross net debugger */
  1016. X                    /* 16 - Chaos */
  1017. X# define IP_PROT_UDP    17        /* user datagrams */
  1018. X                    /* 18 - MUX - Multiplexing */
  1019. X                    /* 19 - DCN-MEAS */
  1020. X                    /* 20 - HMP host monitoring */
  1021. X                    /* 21 PRM */
  1022. X# define IP_PROT_IDP    22        /* xns idp */
  1023. X                    /* 23 TRUNK1 */
  1024. X                    /* 24 TRUNK2 */
  1025. X                    /* 25 LEAF1 */
  1026. X                    /* 26 LEAF2 */
  1027. X                    /* 27 RDP */
  1028. X                    /* 28 IRTP - reliable transaction */
  1029. X                    /* 29 ISO-TP4 */
  1030. X                    /* 30 NETBLT */
  1031. X                    /* 61 any host internal protocol */
  1032. X                    /* 62 CFTP */
  1033. X                    /* 63 any local network */
  1034. X                    /* 64 SAT-EXPAK */
  1035. X                    /* 65 MIT-SUBNET */
  1036. X                    /* 66 - RVD */
  1037. X                    /* 67 IPPC */
  1038. X                    /* 68 any DFS */
  1039. X                    /* 69 SAT-MON */
  1040. X                    /* 71 IPCV */
  1041. X                    /* 76 BR-SAT-MON */
  1042. X                    /* 78 WB-MON */
  1043. X                    /* 79 WB-EXPAK */
  1044. X# define IP_PROT_ND    77        /* net disk (SUN, unoff) */
  1045. X
  1046. X
  1047. X/****************************************************************/
  1048. Xstruct udpheader {
  1049. X    u_short udp_srcp;            /* source port */
  1050. X    u_short udp_dstp;            /* dest port */
  1051. X    u_short udp_len;            /* length of UDP packet */
  1052. X    u_short udp_cksum;            /* UDP checksum */
  1053. X};
  1054. X
  1055. X/****************************************************************/
  1056. Xstruct tcpheader {            /* a tcp header */
  1057. X    u_short tcp_srcp;            /* source port */
  1058. X    u_short tcp_dstp;            /* dest port */
  1059. X    u_long tcp_seq;            /* sequence number */
  1060. X    u_long tcp_ack;            /* acknowledgement number */
  1061. X# if 0
  1062. X    u_short tcp_flags;
  1063. X# define tcp_thl    tcp_flags >> 12
  1064. X# define tcp_fin    tcp_flags & 001
  1065. X# define tcp_syn    tcp_flags & 002
  1066. X# define tcp_rst    tcp_flags & 004
  1067. X# define tcp_psh    tcp_flags & 010
  1068. X# define tcp_fack    tcp_flags & 020
  1069. X# define tcp_furg    tcp_flags & 040
  1070. X# else /* not 0 */
  1071. X    unsigned tcp_thl : 4;        /* tcp header length */
  1072. X    unsigned tcp_uu1 : 6;        /* unused */
  1073. X    unsigned tcp_furg : 1;        /* urgent ptr. valid */
  1074. X    unsigned tcp_fack : 1;        /* ack valid */
  1075. X    unsigned tcp_psh : 1;        /* push bit */
  1076. X    unsigned tcp_rst : 1;        /* reset bit */
  1077. X    unsigned tcp_syn : 1;        /* syn bit */
  1078. X    unsigned tcp_fin : 1;        /* fin bit */
  1079. X# endif /* not 0 */
  1080. X    u_short tcp_win;            /* window */
  1081. X    u_short tcp_cksum;            /* checksum */
  1082. X    u_short tcp_urg;            /* urgent pointer */
  1083. X};
  1084. X
  1085. X/****************************************************************/
  1086. Xstruct ndpacket {
  1087. X    byte nd_op, nd_dev, nd_err, nd_ver;
  1088. X    u_long nd_seq, nd_blk, nd_count, nd_res, nd_off, nd_data;
  1089. X};
  1090. X
  1091. X/****************************************************************/
  1092. Xstruct arppacket {
  1093. X    u_short    arp_hw;            /* should be 1 */
  1094. X    u_short    arp_pro;
  1095. X    byte    arp_hln;        /* hdw addr len */
  1096. X    byte    arp_pln;        /* proto addr len */
  1097. X    u_short    arp_op;            /* arp opcode */
  1098. X    byte    arp_data[1];        /* data... */
  1099. X/*  EA        arp_xsha;        /* sender hardware address */
  1100. X/*  ip_addr    arp_xspa;        /* sender protocol address */
  1101. X/*  EA        arp_xtha;        /* target hardware address */
  1102. X/*  ip_addr    arp_xtpa;        /* target protocol address */
  1103. X};
  1104. X
  1105. X# define ARP_REQUEST    1        /* request to resolve address */
  1106. X# define ARP_REPLY    2        /* response to previous request */
  1107. X# define RARP_REQUEST    3        /* request to resolve address */
  1108. X# define RARP_REPLY    4        /* response to previous request */
  1109. X
  1110. X/* as of rfc990 */
  1111. X# define ARP_HW_ETHER    1        /* 10mb ether */
  1112. X# define ARP_HW_XETHER    2        /* 3mb ether */
  1113. X# define ARP_HW_AX25    3        /* amateur radio */
  1114. X# define ARP_HW_PRONET    4
  1115. X# define ARP_HW_CHAOS    5
  1116. X# define ARP_HW_IEEE802    6
  1117. X
  1118. X/****************************************************************/
  1119. Xstruct puppacket {
  1120. X    u_short pup_len;
  1121. X    byte pup_transport;
  1122. X    byte pup_type;
  1123. X    u_long pup_id;
  1124. X    struct {
  1125. X    byte pup_port_net;
  1126. X    byte pup_port_host;        /* swapped? */
  1127. X    u_short pup_port_sock1, pup_port_sock2;
  1128. X    } pup_src, pup_dst;
  1129. X};
  1130. X
  1131. X/****************************************************************/
  1132. Xstruct xns_addr {
  1133. X    byte xnsa_net[4];
  1134. X    byte xnsa_host[6];
  1135. X    u_short xnsa_port;
  1136. X};
  1137. X
  1138. Xstruct xnspacket {            /* xns idp */
  1139. X    u_short xns_sum, xns_len;        /* cksum, len */
  1140. X    byte xns_tc, xns_pt;        /* hops(transport), packet type */
  1141. X    struct xns_addr xns_dst;
  1142. X    struct xns_addr xns_src;
  1143. X};
  1144. X/****************************************************************/
  1145. X
  1146. Xunion {
  1147. X    byte p_bytes[ 2000 ];
  1148. X    struct etherpacket {
  1149. X    EA e_dst;
  1150. X    EA e_src;
  1151. X    u_short e_type;
  1152. X    union {
  1153. X        byte d_bytes[1];
  1154. X        struct ipheader  d_ip;
  1155. X        struct arppacket d_arp;
  1156. X        struct puppacket d_pup;
  1157. X        struct xnspacket d_xns;
  1158. X    } e_data;
  1159. X    } p_ether;
  1160. X} packet;
  1161. END_OF_packet.h
  1162. if test 6347 -ne `wc -c <packet.h`; then
  1163.     echo shar: \"packet.h\" unpacked with wrong size!
  1164. fi
  1165. # end of overwriting check
  1166. fi
  1167. if test -f rlog.c -a "${1}" != "-c" ; then 
  1168.   echo shar: Will not over-write existing file \"rlog.c\"
  1169. else
  1170. echo shar: Extracting \"rlog.c\" \(20469 characters\)
  1171. sed "s/^X//" >rlog.c <<'END_OF_rlog.c'
  1172. X/*
  1173. X * Copyright (c) 1988 Philip L. Budne and The Trustees of Boston University
  1174. X * All Rights Reserved
  1175. X *
  1176. X * Permission is granted to any individual or institution to use, copy,
  1177. X * or redistribute this software so long as it is not sold for profit,
  1178. X * provided that this notice and the original copyright notices are
  1179. X * retained.  Boston University makes no representations about the
  1180. X * suitability of this software for any purpose.  It is provided "as is"
  1181. X * without express or implied warranty.
  1182. X */
  1183. X# include <stdio.h>
  1184. X# include <ctype.h>
  1185. X# include "packet.h"
  1186. X
  1187. X# define EP_PUP        0x0200
  1188. X# define EP_XNS        0x0600
  1189. X# define EP_IP        0x0800
  1190. X# define EP_CHAOS    0x0804
  1191. X# define EP_ARP        0x0806
  1192. X# define EP_TRAIL    0x1000        /* TO DO! */
  1193. X# define EP_RARP    0x8035        /* TO DO! */
  1194. X# define EP_CTP        0x9000
  1195. X
  1196. Xint    dumpdata = 1;
  1197. Xint    indent = 0;
  1198. X
  1199. X/* counts: */
  1200. Xint    count        = 0;
  1201. Xint     ipcount    = 0;
  1202. Xint      icmpcount    = 0;
  1203. Xint      tcpcount    = 0;
  1204. Xint      udpcount    = 0;
  1205. Xint      ndcount    = 0;
  1206. Xint      ippupcount    = 0;
  1207. Xint      ipidpcount    = 0;
  1208. Xint      egpcount    = 0;
  1209. Xint      ggpcount    = 0;
  1210. Xint      ipfragcount   = 0;
  1211. Xint      ipothercount    = 0;
  1212. Xint      ipbadvercount    = 0;
  1213. Xint     arpcount    = 0;
  1214. Xint     rarpcount    = 0;
  1215. Xint     ieeecount    = 0;
  1216. Xint     pupcount    = 0;
  1217. Xint     xnscount    = 0;
  1218. Xint     othercount    = 0;
  1219. Xint     ctpcount    = 0;
  1220. X
  1221. X/****************************************************************/
  1222. X# include "protocol.h"
  1223. Xint pr_count[ NPROTO ];
  1224. X/****************************************************************/
  1225. X
  1226. Xint pc;                    /* packet byte count */
  1227. X
  1228. Xmain() {
  1229. X    char line[ 4096 ];
  1230. X    register byte *pp;
  1231. X    register char *lp;
  1232. X
  1233. X    pc = 0;
  1234. X    pp = packet.p_bytes;
  1235. X    while( gets( line ) ) {
  1236. X    if( line[0] == ' ' || line[0] == '*' || line[0] == '\0' ) {
  1237. X        if( pc > 0 )
  1238. X        process();
  1239. X        pp = packet.p_bytes;
  1240. X        pc = 0;
  1241. X        continue;
  1242. X    }
  1243. X
  1244. X    for( lp = line; *lp; lp++ ) {
  1245. X        if( isspace( *lp ) )
  1246. X        continue;
  1247. X        else if( isxdigit( *lp ) && isxdigit( lp[1] ) ) {
  1248. X        *pp++ = xval( *lp, lp[1] );
  1249. X        lp++;
  1250. X        pc++;
  1251. X        }
  1252. X        else
  1253. X        fprintf( stderr, "you lose: %s\n", lp );
  1254. X    }
  1255. X    }
  1256. X    if( pc > 0 )
  1257. X    process();
  1258. X    dump_stats();
  1259. X}
  1260. X
  1261. Xprocess() {
  1262. X    register struct etherpacket *e = (struct etherpacket *) &packet;
  1263. X    u_short type;
  1264. X
  1265. X    count++;
  1266. X
  1267. X    terpri();
  1268. X    printf("Packet #%d\n", count );
  1269. X
  1270. X    type = packet.p_ether.e_type;
  1271. X    printf("Ether type %02X-%02X len %d ",
  1272. X       (type >> 8) & 255, type & 255, pc );
  1273. X
  1274. X
  1275. X    petaddr( e->e_src );
  1276. X    putchar(' ');
  1277. X    putchar('>');
  1278. X    putchar(' ');
  1279. X    petaddr( e->e_dst );
  1280. X    terpri();
  1281. X
  1282. X    switch( type ) {
  1283. X    case EP_PUP:
  1284. X    process_pup();
  1285. X    break;
  1286. X    case EP_IP:
  1287. X    process_ip( 1, &packet.p_ether.e_data.d_ip );
  1288. X    break;
  1289. X    case EP_ARP:
  1290. X    process_arp();
  1291. X    break;
  1292. X    case EP_RARP:
  1293. X    process_rarp();
  1294. X    break;
  1295. X    case EP_XNS:
  1296. X    process_xns();
  1297. X    break;
  1298. X    case EP_CTP:
  1299. X    process_ctp();
  1300. X    break;
  1301. X    default:
  1302. X# ifdef IEEE
  1303. X    if( packet.p_ether.e_type < 0x0600 )
  1304. X        process_ieee( type );
  1305. X    else
  1306. X# endif /* IEEE defined */
  1307. X        process_other( type );
  1308. X    break;
  1309. X    }
  1310. X    fflush( stdout );
  1311. X    fflush( stderr );
  1312. X}
  1313. X
  1314. Xprocess_ip( live, i )
  1315. X    int live;                /* true if a real packet */
  1316. X                    /* false for icmp sent headers */
  1317. X    register struct ipheader *i;
  1318. X{
  1319. X    register byte *d, *op;
  1320. X    int size;
  1321. X
  1322. X    if( live) 
  1323. X    ipcount++;
  1324. X
  1325. X    if( i->ip_ver != 4 ) {
  1326. X    printf("IP version not 4 (%d)", i->ip_ver );
  1327. X    terpri();
  1328. X    ipbadvercount++;
  1329. X    return;
  1330. X    }
  1331. X
  1332. X    printf("IP ");
  1333. X    pipaddr( 1, i->ip_src );
  1334. X    printf(" > ");
  1335. X    pipaddr( 1, i->ip_dst );
  1336. X
  1337. X    printf(" len %d",i->ip_len );
  1338. X
  1339. X    if( i->ip_flgs & IP_FLG_DF )    /* don't frag */
  1340. X    printf(" df");
  1341. X
  1342. X    if( i->ip_flgs & IP_FLG_MF )    /* more frags/last frag */
  1343. X    printf(" mf");
  1344. X
  1345. X/*    if( i->ip_ttl != 0 && i->ip_ttl != 255 ) /**/
  1346. X    printf(" ttl %d", i->ip_ttl );
  1347. X
  1348. X    if( i->ip_tsrv != 0 ) {
  1349. X    if( (i->ip_tsrv>>5) & 07 )
  1350. X        printf(" prec %d", ((i->ip_tsrv>>5) & 07) );
  1351. X    if( i->ip_tsrv & 020 )
  1352. X        printf(" low_delay");
  1353. X    if( i->ip_tsrv & 010 )
  1354. X        printf(" hi_thruput");
  1355. X    if( i->ip_tsrv & 04 )
  1356. X        printf(" hi_rely");
  1357. X    }
  1358. X
  1359. X    /* more frags or offset? */
  1360. X    printf(" id %d", i->ip_id );
  1361. X    printf(" off %d", i->ip_foff << 3 );
  1362. X
  1363. X    if( (i->ip_flgs & (IP_FLG_MF|IP_FLG_DF)) || i->ip_foff != 0 ) {
  1364. X    if( i->ip_foff ) {
  1365. X        if( live )
  1366. X        ipfragcount++;
  1367. X    }
  1368. X    }
  1369. X    terpri();
  1370. X
  1371. X    d = ((byte *)(i)) + (i->ip_ihl << 2); /* point to data */
  1372. X
  1373. X    /* options processing!! never tested */
  1374. X    op = i->ip_options;
  1375. X    while( op < d ) {
  1376. X    if( *op & 0200 )
  1377. X        printf(" copy");
  1378. X
  1379. X    switch( ((*op)>>5)&03 ) {    /* print option class */
  1380. X                    /* perhaps only for unkn types? */
  1381. X    case 0:
  1382. X        printf(" control");
  1383. X        break;
  1384. X    case 2:
  1385. X        printf(" debug/meas");
  1386. X        break;
  1387. X    case 1:
  1388. X        printf(" reserved1");
  1389. X        break;
  1390. X    case 3:
  1391. X        printf(" reserved3");
  1392. X        break;
  1393. X    }
  1394. X
  1395. X    switch( (*op) & 017 ) {
  1396. X    case 0:                /* end of list */
  1397. X        goto end_of_options;
  1398. X        
  1399. X    case 1:
  1400. X        printf(" noop");
  1401. X        op++;
  1402. X        break;
  1403. X        
  1404. X    case 2:
  1405. X        printf(" security %02X %02X", op[2], op[3] );
  1406. X        op += op[1];            /* should be 11 */
  1407. X        break;
  1408. X        
  1409. X    case 3:
  1410. X        printf(" LS+RR");        /* loose source */
  1411. X        /* print more info! */
  1412. X        op += op[1];
  1413. X        break;
  1414. X        
  1415. X    case 4:
  1416. X        printf(" TIMESTAMP");
  1417. X        switch( op[3] &0xf ) {
  1418. X        case 0:
  1419. X        break;            /* time stamps only */
  1420. X        case 1:
  1421. X        printf("+ADDRESS");
  1422. X        break;
  1423. X        
  1424. X        case 2:
  1425. X        printf(" ?flag 2?");
  1426. X        break;
  1427. X        
  1428. X        case 3:
  1429. X        printf(" (prespec)");
  1430. X        break;
  1431. X        }
  1432. X        
  1433. X        if( op[3] & 0xf0 )
  1434. X        printf(" %d overflows", (op[3]>>4)&0xf );
  1435. X        
  1436. X        op += op[1];
  1437. X        break;
  1438. X        
  1439. X    case 7:
  1440. X        printf(" RR");
  1441. X        /* print more info! */
  1442. X        op += op[1];
  1443. X        break;
  1444. X        
  1445. X    case 8:
  1446. X        printf(" SATNET_Stream_ID");
  1447. X        /* print more info! */
  1448. X        op += op[1];            /* should be 4 */
  1449. X        break;
  1450. X        
  1451. X    case 9:
  1452. X        printf(" SS+RR");        /* strict source */
  1453. X        /* print more info! */
  1454. X        op += op[1];
  1455. X        break;
  1456. X        
  1457. X    default:
  1458. X        printf(" option %d.", *op&017 );
  1459. X        op += op[1];
  1460. X        break;
  1461. X    } /* switch on option number */
  1462. X    terpri();
  1463. X    } /* while op */
  1464. X
  1465. Xend_of_options: ;
  1466. X
  1467. X    if( i->ip_foff != 0 && live ) {
  1468. X    printf("  FRAGMENT (proto %d.)", i->ip_prot );
  1469. X    terpri();
  1470. X    return;                /* ?? */
  1471. X    }
  1472. X
  1473. X    size = pc - (d - packet.p_bytes);
  1474. X
  1475. X    switch( i->ip_prot ) {
  1476. X    case IP_PROT_UDP:
  1477. X    if( live )
  1478. X        udpcount++;
  1479. X    process_ip_udp( d, size );
  1480. X    break;
  1481. X    case IP_PROT_TCP:
  1482. X    if( live )
  1483. X        tcpcount++;
  1484. X    process_ip_tcp( d, size );
  1485. X    break;
  1486. X    case IP_PROT_ND:
  1487. X    if( live )
  1488. X        ndcount++;
  1489. X    process_ip_nd( d, size );
  1490. X    break;
  1491. X    case IP_PROT_ICMP:
  1492. X    if( live )
  1493. X        icmpcount++;
  1494. X    process_ip_icmp( d );
  1495. X    break;
  1496. X    case IP_PROT_GGP:
  1497. X    printf("GGP");
  1498. X    terpri();
  1499. X    if( live )
  1500. X        ggpcount++;
  1501. X    /* process?? */
  1502. X    break;
  1503. X    case IP_PROT_EGP:
  1504. X    printf("EGP");
  1505. X    terpri();
  1506. X    if( live )
  1507. X        egpcount++;
  1508. X    /* process?? */
  1509. X    break;
  1510. X    case IP_PROT_PUP:
  1511. X    printf("PUP-IP");
  1512. X    terpri();
  1513. X    if( live )
  1514. X        ippupcount++;
  1515. X    break;
  1516. X    case IP_PROT_IDP:            /* xns idp */
  1517. X    printf("IDP-IP (xns)");
  1518. X    terpri();
  1519. X    if( live )
  1520. X        ipidpcount++;
  1521. X    /* process?? */
  1522. X    break;
  1523. X    default:
  1524. X    printf(" ipproto %d", i->ip_prot );
  1525. X    terpri();
  1526. X    if( live )
  1527. X        ipothercount++;
  1528. X    }
  1529. X}
  1530. X
  1531. Xprocess_ip_udp( d )
  1532. Xbyte *d;
  1533. X{
  1534. X    register struct udpheader *u = (struct udpheader *) d;
  1535. X    printf("UDP srcp: %d destp: %d", u->udp_srcp, u->udp_dstp );
  1536. X    terpri();
  1537. X}
  1538. X
  1539. Xprocess_ip_tcp( d, size )
  1540. Xbyte *d;
  1541. X{
  1542. X    register struct tcpheader *t = (struct tcpheader *) d;
  1543. X    register byte *o, *td;
  1544. X    int c, l;
  1545. X
  1546. X    printf("TCP srcp: %d destp: %d", t->tcp_srcp, t->tcp_dstp );
  1547. X
  1548. X    if( t->tcp_furg )
  1549. X    printf(" urg %#x", t->tcp_urg );
  1550. X    if( t->tcp_fack )
  1551. X    printf(" ack %#x", t->tcp_ack );
  1552. X    if( t->tcp_psh )
  1553. X    printf(" psh");
  1554. X    if( t->tcp_rst )
  1555. X    printf(" rst");
  1556. X    if( t->tcp_syn )
  1557. X    printf(" syn");
  1558. X    if( t->tcp_fin )
  1559. X    printf(" fin");
  1560. X    printf(" window %d.", t->tcp_win );
  1561. X
  1562. X    c = ((t->tcp_thl) << 2);        /* get tcp data offset */
  1563. X
  1564. X    size -= c;                /* get size of data */
  1565. X    td = d + c;                /* start of tcp data */
  1566. X
  1567. X    printf(" data %d.", size );
  1568. X
  1569. X    o = d + sizeof( struct tcpheader );    /* get start of options */
  1570. X    c -= sizeof( struct tcpheader );    /* get size of options */
  1571. X
  1572. X    while( c > 0 ) {            /* process tcp options */
  1573. X    switch( *o ) {
  1574. X    case 0:                /* end of list */
  1575. X        goto break_options_loop;
  1576. X
  1577. X    case 1:                /* nop */
  1578. X        l = 1;
  1579. X        break;
  1580. X
  1581. X    case 2:                /* mss */
  1582. X        l = o[1];
  1583. X        if( l != 4 ) {
  1584. X        printf("BAD_mss"); 
  1585. X        }
  1586. X        else
  1587. X        printf(" mss %d", *((u_short *)(&o[2])) );
  1588. X        break;
  1589. X
  1590. X    default:
  1591. X        l = o[1];
  1592. X        printf(" option %d. (len %d.)", *o, l );
  1593. X        break;
  1594. X    } /* switch */
  1595. X    o += l;
  1596. X    c -= l;
  1597. X    } /* tcp options loop */
  1598. X break_options_loop:;
  1599. X
  1600. X    terpri();
  1601. X
  1602. X    if( dumpdata ) {
  1603. X    while( size-- > 0 )
  1604. X        putbyte( *td++ );
  1605. X    terpri();
  1606. X    }
  1607. X} /* process_ip_tcp */
  1608. X
  1609. Xputbyte( c ) {
  1610. X    if( c >= ' ' && c <= 0176 )
  1611. X    putchar( c );
  1612. X    else
  1613. X    switch( c ) {
  1614. X    case '\n':
  1615. X        printf("\\n");
  1616. X        break;
  1617. X    case '\r':
  1618. X        printf("\\r");
  1619. X        break;
  1620. X    case '\f':
  1621. X        printf("\\f");
  1622. X        break;
  1623. X    /* ** MORE ESCAPES ** @@ */
  1624. X    default:
  1625. X        printf("\\%#o", c & 0xff );
  1626. X        break;
  1627. X    } /* switch */
  1628. X} /* putbyte */
  1629. X
  1630. Xprocess_ip_icmp( d )
  1631. Xbyte *d;
  1632. X{
  1633. X    register struct icmppacket {
  1634. X    byte icmp_type, icmp_code;
  1635. X    u_short icmp_cksum;
  1636. X    union {
  1637. X        u_short id_short[2];
  1638. X        u_long  id_long[1];
  1639. X        byte    id_byte[4];
  1640. X    } icmp_data;
  1641. X    struct ipheader icmp_ip;
  1642. X    } *i = (struct icmppacket *) d;
  1643. X
  1644. X    static char *icmp_unreach_names[] = {
  1645. X    "net", "host", "proto", "port", "need frag", "srcroute failed" };
  1646. X# define N_ICMP_UNREACH_NAMES (sizeof( icmp_unreach_names ) / sizeof( char * ))
  1647. X
  1648. X    printf("ICMP ");
  1649. X    switch( i->icmp_type ) {
  1650. X    case 0:                /* ECHOREPLY */
  1651. X    case 8:                /* ECHO */
  1652. X    printf("echo");
  1653. X    if( i->icmp_type == 0 )
  1654. X        printf(" reply");
  1655. X    printf(" id %d seq %d data: ",
  1656. X           i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
  1657. X    pbytes( &i->icmp_data.id_byte[4], 16 );
  1658. X    terpri();
  1659. X    return;
  1660. X    break;
  1661. X
  1662. X    case 3:                /* ICMP_UNREACH */
  1663. X    if( i->icmp_code < N_ICMP_UNREACH_NAMES )
  1664. X        printf("unreachable %s", icmp_unreach_names[ i->icmp_code ] );
  1665. X    else
  1666. X        printf("unreachable (code %d)", i->icmp_code );
  1667. X    break;
  1668. X
  1669. X    case 4:
  1670. X    printf("source quench");
  1671. X    break;
  1672. X
  1673. X    case 5:                /* ICMP_REDIRECT */
  1674. X    printf("redirect");
  1675. X    if( i->icmp_code == 0 )
  1676. X        printf(" net");
  1677. X    else if( i->icmp_code == 1 )
  1678. X        printf(" host");
  1679. X    else if( i->icmp_code == 2 )
  1680. X        printf(" tos/net");
  1681. X    else if( i->icmp_code == 3 )
  1682. X        printf(" tos/host");
  1683. X    else
  1684. X        printf(" (code %d)", i->icmp_code );
  1685. X    printf(" to ");
  1686. X    pipaddr( 1, i->icmp_data.id_long[0] );
  1687. X    break;
  1688. X
  1689. X    case 11:
  1690. X    switch( i->icmp_code ) {
  1691. X    case 0:
  1692. X        printf("ttl exceeded");
  1693. X        break;
  1694. X    case 1:
  1695. X        printf("reassembly ttl exceeded");
  1696. X        break;
  1697. X    default:
  1698. X        printf("time exceeded code %d", i->icmp_code );
  1699. X        break;
  1700. X    }
  1701. X    break;
  1702. X
  1703. X    case 12:
  1704. X    printf("parmeter problem at %d", i->icmp_data.id_byte[0] );
  1705. X    break;
  1706. X
  1707. X    case 13:
  1708. X    case 14:
  1709. X    printf("timestamp");
  1710. X    if( i->icmp_type == 14 )
  1711. X        printf(" reply");
  1712. X    printf(" id %d seq %d",
  1713. X           i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
  1714. X    terpri();
  1715. X    printf("orig ");
  1716. X    ptime( i->icmp_data.id_long[1] );
  1717. X
  1718. X    if( i->icmp_type == 14 ) {    /* reply */
  1719. X        printf(" rcv ");
  1720. X        ptime( i->icmp_data.id_long[2] );
  1721. X        printf(" xmit ");
  1722. X        ptime( i->icmp_data.id_long[3] );
  1723. X    }
  1724. X    terpri();
  1725. X    return;
  1726. X    break;
  1727. X
  1728. X    case 15:
  1729. X    printf("info request id %d seq %d",
  1730. X           i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
  1731. X    terpri();
  1732. X    return;
  1733. X    break;
  1734. X
  1735. X    case 16:
  1736. X    printf("info reply id %d seq %d",
  1737. X           i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
  1738. X    terpri();
  1739. X    return;
  1740. X    break;
  1741. X
  1742. X    case 17:
  1743. X    printf("mask request id %d seq %d",
  1744. X           i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
  1745. X    terpri();
  1746. X    return;                /* no enacpsulated packet */
  1747. X    break;
  1748. X
  1749. X    case 18:
  1750. X    printf("mask reply id %d seq %d ",
  1751. X           i->icmp_data.id_short[0], i->icmp_data.id_short[1] );
  1752. X    pipaddr( 0, i->icmp_data.id_long[1] );
  1753. X    terpri();
  1754. X    return;                /* no enacpsulated packet */
  1755. X    break;
  1756. X
  1757. X    default:
  1758. X    printf("type %d", i->icmp_type );
  1759. X    if( i->icmp_code != 0 )
  1760. X        printf(" (code %d)", i->icmp_code );
  1761. X    printf(" data: ");
  1762. X    pbytes( i->icmp_data.id_byte, 4 );
  1763. X    terpri();
  1764. X    return;                /* no enacpsulated packet?? */
  1765. X    break;
  1766. X    }
  1767. X
  1768. X    indent += 4;
  1769. X    terpri();
  1770. X    process_ip( 0, &i->icmp_ip );    /* RECURSE!! */
  1771. X    indent -= 4;
  1772. X    terpri();
  1773. X}
  1774. X
  1775. Xptime( t )
  1776. Xu_long t;
  1777. X{
  1778. X    int h, m, s;
  1779. X    if( t & 0x40000000 ) {
  1780. X    printf( "%d.", t & 0xbfffffff );
  1781. X    return;
  1782. X    }
  1783. X    s = t / 1000;
  1784. X    m = s / 60;
  1785. X    h = m / 60;
  1786. X
  1787. X    m %= 60;
  1788. X    s %= 60;
  1789. X    t %= 1000;
  1790. X    if( h > 0 )
  1791. X    printf("%dh", h );
  1792. X    if( m > 0 )
  1793. X    printf("%dm", m  );
  1794. X    printf("%d.%03d", s, t );
  1795. X}
  1796. X
  1797. Xprocess_ip_nd( d )
  1798. Xbyte *d;
  1799. X{
  1800. X    register struct ndpacket *n = (struct ndpacket *) d;
  1801. X
  1802. X    printf("ND");
  1803. X
  1804. X    switch( n->nd_op & 7 ) {
  1805. X    case 1:
  1806. X    printf(" read");
  1807. X    break;
  1808. X    case 2:
  1809. X    printf(" write");
  1810. X    break;
  1811. X    case 3:
  1812. X    printf(" error");
  1813. X    break;
  1814. X    default:
  1815. X    printf(" op %d", n->nd_op & 7 );
  1816. X    break;
  1817. X    }
  1818. X    if( n->nd_op & 010 )
  1819. X    printf(" wait");
  1820. X    if( n->nd_op & 020 )
  1821. X    printf(" done");
  1822. X
  1823. X    printf(" /dev/nd");
  1824. X    if( n->nd_dev > 0177 )
  1825. X    putchar('l');
  1826. X    else if( n->nd_dev > 077 )
  1827. X    putchar('p');
  1828. X    printf("%d seq %d",  n->nd_dev & 077, n->nd_seq );
  1829. X    printf(" block %d count %d",
  1830. X       n->nd_blk, n->nd_count);
  1831. X    if( n->nd_res > 0 )
  1832. X    printf(" resid %d", n->nd_res );
  1833. X    if( n->nd_off > 0 )
  1834. X    printf(" off %d",
  1835. X           n->nd_off );
  1836. X    if( n->nd_data > 0 )
  1837. X    printf(" data %d",
  1838. X           n->nd_data );
  1839. X    terpri();
  1840. X}
  1841. X
  1842. Xprocess_arp() {
  1843. X    arpcount++;
  1844. X    printf("ARP");
  1845. X    process_arp2(0);
  1846. X}
  1847. X
  1848. X# define EA_NZERO(p) ( (*(long *)p) != 0 && (*(short *)(p+4)) != 0 )
  1849. X
  1850. Xprocess_arp2(israrp) {
  1851. X    register struct arppacket *a = &packet.p_ether.e_data.d_arp;
  1852. X    register struct protocol *pp;
  1853. X    int xsha, xspa, xtha, xtpa;
  1854. X    ip_addr i;
  1855. X
  1856. X    xsha = 0;                /* sender hdw addr */
  1857. X    xspa = a->arp_hln;            /* sender proto addr */
  1858. X    xtha = xspa + a->arp_pln;        /* target hdw addr */
  1859. X    xtpa = xtha + a->arp_hln;        /* target proto addr */
  1860. X
  1861. X    switch( a->arp_hw ) {
  1862. X    case ARP_HW_ETHER:
  1863. X    break;
  1864. X    case ARP_HW_XETHER:
  1865. X    printf(" 3Mb ether");
  1866. X    break;
  1867. X    case ARP_HW_AX25:
  1868. X    printf(" AX.25");
  1869. X    break;
  1870. X    case ARP_HW_PRONET:
  1871. X    printf(" PROnet");
  1872. X    break;
  1873. X    case ARP_HW_CHAOS:
  1874. X    printf(" Chaos");
  1875. X    break;
  1876. X    case ARP_HW_IEEE802:
  1877. X    printf(" IEEE 802");
  1878. X    break;
  1879. X    }
  1880. X
  1881. X    switch( a->arp_pro ) {
  1882. X    case EP_IP:
  1883. X    case EP_TRAIL:
  1884. X    printf(" IP");
  1885. X    if( a->arp_pro == EP_TRAIL )
  1886. X        printf(" trailers");
  1887. X    if( a->arp_op == ARP_REQUEST )
  1888. X        printf(" request ");
  1889. X    else if( a->arp_op == RARP_REQUEST )
  1890. X        printf(" reverse request ");
  1891. X    else if( a->arp_op == RARP_REPLY )
  1892. X        printf(" reverse reply ");
  1893. X    else
  1894. X        printf(" op %d ", a->arp_op );
  1895. X
  1896. X    printf("source");
  1897. X    if( EA_NZERO( a->arp_data + xsha ) ) {
  1898. X        putchar(' ');
  1899. X        petaddr( a->arp_data + xsha );
  1900. X    }
  1901. X    i = * (ip_addr *) (a->arp_data + xspa);
  1902. X    if( i != 0 ) {
  1903. X        putchar(' ');
  1904. X        pipaddr( 1, i );
  1905. X    }
  1906. X    terpri();
  1907. X
  1908. X    printf("target");
  1909. X    if( EA_NZERO( a->arp_data + xtha ) ) {
  1910. X        putchar(' ');
  1911. X        petaddr( a->arp_data + xtha );
  1912. X    }
  1913. X    i = * (ip_addr *) (a->arp_data + xtpa);
  1914. X    if( i != 0 ) {
  1915. X        putchar(' ');
  1916. X        pipaddr( 1, i );
  1917. X    }
  1918. X    terpri();
  1919. X    return;
  1920. X
  1921. X    case EP_CHAOS:
  1922. X    printf(" CHAOS ");
  1923. X    if( a->arp_op == ARP_REQUEST )
  1924. X        printf(" request ");
  1925. X    else if( a->arp_op == ARP_REPLY )
  1926. X        printf(" reply to ");
  1927. X    else
  1928. X        printf("op %d ", a->arp_op );
  1929. X
  1930. X    printf("source ");
  1931. X    petaddr( a->arp_data + xsha );
  1932. X    putchar( ' ' );
  1933. X    printf("%#o ", * (u_short *) (a->arp_data + xspa) );
  1934. X    terpri();
  1935. X
  1936. X    printf("target ");
  1937. X    petaddr( a->arp_data + xtha );
  1938. X    putchar(' ');
  1939. X    printf("%#o ", * (u_short *) (a->arp_data + xtpa) );
  1940. X    terpri();
  1941. X
  1942. X    return;
  1943. X
  1944. X    default:
  1945. X    for( pp = protocols; pp->pr_type != 0; pp++ )
  1946. X        if( a->arp_pro == pp->pr_type ) {
  1947. X        printf("%s ???", pp->pr_name );
  1948. X        terpri();
  1949. X        return;
  1950. X        }
  1951. X    printf("%02X-%02X ???", (a->arp_pro >> 8) & 255,
  1952. X           a->arp_pro & 255 );
  1953. X    terpri();
  1954. X    }
  1955. X}
  1956. X
  1957. Xprocess_ieee( l )
  1958. Xu_short l;
  1959. X{
  1960. X    ieeecount++;
  1961. X    printf("IEEE len %d", l );
  1962. X    terpri();
  1963. X}
  1964. X
  1965. Xprocess_pup() {
  1966. X    register struct puppacket *p = &packet.p_ether.e_data.d_pup;
  1967. X    pupcount++;
  1968. X    printf("PUP len %d transport %d type %#o id %d",
  1969. X       p->pup_len, p->pup_transport, p->pup_type );
  1970. X    terpri();
  1971. X    printf("src net %#o host %#o socket %#o",
  1972. X       p->pup_src.pup_port_net,
  1973. X       p->pup_src.pup_port_host,
  1974. X       (p->pup_src.pup_port_sock1) << 16 +
  1975. X       p->pup_src.pup_port_sock2 );
  1976. X    terpri();
  1977. X    printf("dst net %#o host %#o socket %#o",
  1978. X       p->pup_dst.pup_port_net,
  1979. X       p->pup_dst.pup_port_host,
  1980. X       (p->pup_dst.pup_port_sock1) << 16 +
  1981. X       p->pup_dst.pup_port_sock2 );
  1982. X    terpri();
  1983. X}
  1984. X
  1985. Xprocess_rarp() {
  1986. X    rarpcount++;
  1987. X    printf("RARP");
  1988. X    process_arp2(1);
  1989. X}
  1990. X
  1991. X# define CTP_REP 1
  1992. X# define CTP_FWD 2
  1993. X# define CTP_SHORT(sp) (*sp | (sp[1]<<8))
  1994. X
  1995. Xprocess_ctp() {
  1996. X    byte *p2, *p = packet.p_ether.e_data.d_bytes;
  1997. X    short f, skip;
  1998. X    int len, l2;
  1999. X
  2000. X    ctpcount++;
  2001. X    skip = CTP_SHORT(p);
  2002. X    p2 = p + skip + 2;            /* point to data (skip skip!) */
  2003. X    len = pc - 14 - skip - 2;        /* length of data */
  2004. X
  2005. X    printf("CTP skip %d.", skip );
  2006. X    terpri();
  2007. X    for( ; ; ) {
  2008. X    if( len < 2 )
  2009. X        return;
  2010. X
  2011. X    f = CTP_SHORT( p2 );        /* get function */
  2012. X    p2 += 2;            /* advance past function */
  2013. X    len -= 2;            /* account for function length */
  2014. X    switch( f ) {
  2015. X    case CTP_REP:            /* reply */
  2016. X        printf(" REPLY data: ");
  2017. X        goto break_for;
  2018. X        break;
  2019. X
  2020. X    case CTP_FWD:            /* forward */
  2021. X        if( len < 6 ) {
  2022. X        printf("Too little data for FORWARD packet");
  2023. X        terpri();
  2024. X        return;
  2025. X        }
  2026. X        printf(" FORWARD to: ");
  2027. X        petaddr( p2 );        /* print ether addr */
  2028. X        terpri();
  2029. X        p2 += 6;            /* advance data */
  2030. X        len -=6;            /* account for len */
  2031. X        break;
  2032. X
  2033. X    default:
  2034. X        printf(" fncn %d. data: ", f );
  2035. X        goto break_for;
  2036. X    }
  2037. X    }
  2038. X break_for: ;
  2039. X    l2 = len;
  2040. X    if( l2 > 32 )
  2041. X    l2 = 32;
  2042. X    pbytes( p2, l2 );
  2043. X    if( len > 32 )
  2044. X    printf("...");
  2045. X    terpri();
  2046. X}
  2047. X
  2048. Xprocess_xns() {
  2049. X    register struct xnspacket *x = &packet.p_ether.e_data.d_xns;
  2050. X    xnscount++;
  2051. X    printf("XNS IDP len %d transport %d type %d",
  2052. X       x->xns_len, x->xns_tc, x->xns_pt );
  2053. X    terpri();
  2054. X    printf("src: ");
  2055. X    pxnsaddr( &x->xns_src );
  2056. X    terpri();
  2057. X
  2058. X    printf("dst: ");
  2059. X    pxnsaddr( &x->xns_dst );
  2060. X    terpri();
  2061. X}
  2062. X
  2063. Xpxnsaddr( xa )
  2064. X    register struct xns_addr *xa;
  2065. X{
  2066. X    pbytes( xa->xnsa_net, 4 );
  2067. X    putchar(':');
  2068. X    pbytes( xa->xnsa_host, 6 );
  2069. X    printf(" port %d", xa->xnsa_port );
  2070. X}
  2071. X
  2072. Xprocess_other( type )
  2073. Xint type;
  2074. X{
  2075. X    register struct protocol *pp;
  2076. X    register int i;
  2077. X
  2078. X    for( i = 0, pp = protocols; pp->pr_type != 0; i++, pp++ )
  2079. X    if( type == pp->pr_type ) {
  2080. X        printf( "%s", pp->pr_name );
  2081. X        terpri();
  2082. X        pr_count[ i ]++;
  2083. X        pbytes( packet.p_ether.e_data.d_bytes, 32 );
  2084. X        printf("...");
  2085. X        terpri();
  2086. X        return;
  2087. X    }
  2088. X    else if( type < pp->pr_type )
  2089. X        break;
  2090. X    pbytes( packet.p_ether.e_data.d_bytes, 32 );
  2091. X    printf("...");
  2092. X    terpri();
  2093. X    othercount++;
  2094. X}
  2095. X
  2096. Xdump_stats() {
  2097. X    register struct protocol *pp;
  2098. X    int i;
  2099. X
  2100. X    if( count > 0 )
  2101. X    fprintf( stderr, "count: %d\n", count );
  2102. X    if( ipcount > 0 )
  2103. X    fprintf( stderr, " ipcount: %d\n", ipcount );
  2104. X    if( icmpcount > 0 )
  2105. X    fprintf( stderr, "  icmpcount: %d\n", icmpcount );
  2106. X    if( tcpcount > 0 )
  2107. X    fprintf( stderr, "  tcpcount: %d\n", tcpcount );
  2108. X    if( udpcount > 0 )
  2109. X    fprintf( stderr, "  udpcount: %d\n", udpcount );
  2110. X    if( ndcount > 0 )
  2111. X    fprintf( stderr, "  ndcount: %d\n", ndcount );
  2112. X    if( egpcount > 0 )
  2113. X    fprintf( stderr, "  egpcount: %d\n", egpcount );
  2114. X    if( ggpcount > 0 )
  2115. X    fprintf( stderr, "  ggpcount: %d\n", ggpcount );
  2116. X    if( ippupcount > 0 )
  2117. X    fprintf( stderr, "  ippupcount: %d\n", ippupcount );
  2118. X    if( ipidpcount > 0 )
  2119. X    fprintf( stderr, "  ipidpcount: %d\n", ipidpcount );
  2120. X    if( ipfragcount > 0 )
  2121. X    fprintf( stderr, "  ipfragcount: %d\n", ipfragcount );
  2122. X    if( ipothercount > 0 )
  2123. X    fprintf( stderr, "  ipothercount: %d\n", ipothercount );
  2124. X    if( ipbadvercount > 0 )
  2125. X    fprintf( stderr, "  ipbadvercount: %d\n", ipbadvercount );
  2126. X    if( arpcount > 0 )
  2127. X    fprintf( stderr, " arpcount: %d\n", arpcount );
  2128. X    if( rarpcount > 0 )
  2129. X    fprintf( stderr, " rarpcount: %d\n", rarpcount );
  2130. X    if( ieeecount > 0 )
  2131. X    fprintf( stderr, " ieeecount: %d\n", ieeecount );
  2132. X    if( pupcount > 0 )
  2133. X    fprintf( stderr, " pupcount: %d\n", pupcount );
  2134. X    if( xnscount > 0 )
  2135. X    fprintf( stderr, " xnscount: %d\n", xnscount );
  2136. X    if( ctpcount > 0 )
  2137. X    fprintf( stderr, " ctpcount: %d\n", ctpcount );
  2138. X
  2139. X    for( i = 0, pp = protocols; pp->pr_type != 0; i++, pp++ )
  2140. X    if( pr_count[i] > 0 )
  2141. X        fprintf( stderr, " %s: %d\n", pp->pr_name, pr_count[i] );
  2142. X
  2143. X    if( othercount > 0 )
  2144. X    fprintf( stderr, " othercount: %d\n", othercount );
  2145. X}
  2146. X
  2147. Xterpri() {
  2148. X    register int i = indent;
  2149. X    putchar( '\n' );
  2150. X    while( i-- > 0 )
  2151. X    putchar( ' ' );
  2152. X}
  2153. END_OF_rlog.c
  2154. if test 20469 -ne `wc -c <rlog.c`; then
  2155.     echo shar: \"rlog.c\" unpacked with wrong size!
  2156. fi
  2157. # end of overwriting check
  2158. fi
  2159. echo shar: End of archive 2 \(of 2\).
  2160. cp /dev/null ark2isdone
  2161. MISSING=""
  2162. for I in 1 2 ; do
  2163.     if test ! -f ark${I}isdone ; then
  2164.     MISSING="${MISSING} ${I}"
  2165.     fi
  2166. done
  2167. if test "${MISSING}" = "" ; then
  2168.     echo You have unpacked both archives.
  2169.     rm -f ark[1-9]isdone
  2170. else
  2171.     echo You still need to unpack the following archives:
  2172.     echo "        " ${MISSING}
  2173. fi
  2174. ##  End of shell archive.
  2175. exit 0
  2176.